18 Matplotlib库基础
18.1 引言可视化的重要性
金融数据可视化: - 发现模式: 趋势、周期、异常 - 沟通结果: 图表比数字更直观 - 辅助决策: 支撑交易决策
18.2 基础绘图
平台任务解答代码
以下代码与教学平台任务要求完全一致:
# ⚠️ 平台原始代码 - 请原样输入至教学平台(注释除外),平台才会判定答案正确
# 注:numpy_financial包本地未安装,但平台已经内置
import matplotlib.pyplot as plt # 导入Matplotlib绑图库
plt.rcParams['font.family'] = 'SimHei' # 设置Matplotlib全局参数
plt.rcParams['axes.unicode_minus'] = False # 设置Matplotlib全局参数
import numpy_financial as npf # 导入NumPy数值计算库
import numpy as np # 导入NumPy数值计算库
r=0.05 # 贷款的年利率
n=30 # 贷款的年数
principle=8e6 # 设置期数/数量为8000000
pay_month=npf.ppmt(rate=r/12,per=n*12,nper=n*12,pv=principle,fv=0,when='end') #计算每月支付的本息之和
print('每月的偿还的金额',round(pay_month,2)) # 输出每月的偿还的金额
T_list=np.arange(n*12)+1 #生成一个包含每次还款期限的数组
# 计算每期应还的本金部分
prin_month=npf.ppmt(rate=r/12,per=T_list,nper=n*12,pv=principle,fv=0,when='end')
# 计算每期应还的利息部分
inte_month=npf.ipmt(rate=r/12,per=T_list,nper=n*12,pv=principle,fv=0,when='end')
pay_month_list=pay_month*np.ones_like(prin_month) # 生成与prin_month等长的每月总还款额数组
fig=plt.figure(figsize=(9,6)) # 创建图形画布
ax=fig.add_subplot(111) # 添加单个子图占据整个画布
ax.plot(T_list,-pay_month_list,'r-',label=u'每月偿还金额') # 在子图上绑制曲线
ax.plot(T_list,-prin_month,'m--',label=u'每月偿还本金金额') # 在子图上绑制曲线
ax.plot(T_list,-inte_month,'b--',label=u'每月偿还利息金额') # 在子图上绑制曲线
ax.set_xlabel(u'逐次偿还的期限(月)',fontsize=14) # 设置X轴标签
ax.set_ylabel(u'金额',fontsize=14) # 设置Y轴标签
ax.legend() # 设置图例
plt.savefig("1.png") # 保存图形至文件# =============================================================================
# 题目:按揭贷款本息偿还可视化
# =============================================================================
# 本任务演示如何使用Matplotlib绘制金融时间序列图
# 场景:可视化30年期按揭贷款的本金和利息偿还过程
# ==================== 导入必要的库 ====================
import matplotlib.pyplot as plt # Matplotlib的pyplot模块,提供类似MATLAB的绘图接口
import numpy as np # NumPy数值计算库
# ==================== 按揭贷款参数 ====================
# principal:贷款本金(100万元)
principal = 1000000
# rate:年利率(4.9%,这是典型的商业贷款利率)
rate = 0.049
# years:贷款期限(30年)
years = 30
# ==================== 计算月供(等额本息) ====================
# monthly_rate:月利率 = 年利率 / 12
monthly_rate = rate / 12
# n_months:总月数 = 年数 * 12
n_months = years * 12
# 月供计算公式(等额本息)
# monthly_payment = principal * [r(1+r)^n] / [(1+r)^n - 1]
# 这是标准的按揭贷款月供公式
monthly_payment = principal * (monthly_rate * (1 + monthly_rate)**n_months) / ((1 + monthly_rate)**n_months - 1)
# ==================== 计算每年的本金和利息 ====================
# years_array:年份序列 [1, 2, 3, ..., 30]
years_array = np.arange(1, years + 1)
# balance:剩余本金,初始值为贷款总额
balance = principal
# interest_paid:每年支付的利息列表
interest_paid = []
# principal_paid:每年偿还的本金列表
principal_paid = []
# ==================== 逐年计算本金和利息 ====================
# for循环:遍历每一年
for year in years_array:
# 初始化当年的利息和本金
annual_interest = 0 # 当年累计利息
annual_principal = 0 # 当年累计本金
# 内层循环:遍历当年的12个月
for _ in range(12):
# interest:当月利息 = 剩余本金 * 月利率
interest = balance * monthly_rate
# principal_part:当月本金 = 月供 - 当月利息
principal_part = monthly_payment - interest
# 更新剩余本金:减去当月偿还的本金
balance -= principal_part
# 累加到年度总额
annual_interest += interest
annual_principal += principal_part
# 将年度数据添加到列表
interest_paid.append(annual_interest)
principal_paid.append(annual_principal)
# ==================== 绘图 ====================
# plt.figure():创建画布
# figsize=(10, 6):画布宽度10英寸,高度6英寸
plt.figure(figsize=(10, 6))
# plt.plot():绘制折线图
plt.plot(years_array, interest_paid, label='利息', linewidth=2)
plt.plot(years_array, principal_paid, label='本金', linewidth=2)
# ==================== 设置图表元素 ====================
# plt.xlabel():设置X轴标签
plt.xlabel('年份', fontsize=12)
# plt.ylabel():设置Y轴标签
plt.ylabel('金额(元)', fontsize=12)
# plt.title():设置图表标题
plt.title('按揭贷款30年本金利息分解', fontsize=14)
# plt.legend():显示图例
plt.legend(fontsize=12)
# plt.grid():显示网格线
# alpha=0.3:网格线透明度30%
plt.grid(True, alpha=0.3)
# ==================== 添加注释 ====================
# plt.annotate():在图表上添加文本注释
# xy=(5, interest_paid[4]):箭头指向的坐标(第5年,第5年的利息)
# xytext=(10, interest_paid[4]):文本位置(第10年,第5年的利息高度)
# arrowprops=dict(arrowstyle='->'):箭头样式(单线箭头)
plt.annotate('前期利息占比高', xy=(5, interest_paid[4]), xytext=(10, interest_paid[4]),
arrowprops=dict(arrowstyle='->'))
# ==================== 调整布局并显示 ====================
# plt.tight_layout():自动调整子图间距,避免元素重叠
plt.tight_layout()
# plt.show():显示图表
plt.show()
# ==================== 打印统计信息 ====================
# f-string:格式化字符串
# .2f:保留2位小数
print(f"月供: {monthly_payment:.2f}元")
# 月供 * 月数:总还款额
print(f"总还款: {monthly_payment * n_months:.2f}元")
# 总还款 - 本金:总利息
print(f"总利息: {monthly_payment * n_months - principal:.2f}元")18.3 图表类型
# =============================================================================
# 题目:常用图表类型示例
# =============================================================================
# 本任务演示Matplotlib中常用的四种图表类型
# 应用场景:投资组合数据的多样化展示
# ==================== 导入必要的库 ====================
import matplotlib.pyplot as plt # Matplotlib绘图库
import numpy as np # NumPy数值计算库
# ==================== 创建子图布局 ====================
# plt.subplots(2, 2):创建2行2列的子图布局(共4个图)
# figsize=(12, 10):画布宽度12英寸,高度10英寸
# fig:整个画布对象
# axes:子图数组(2x2的numpy数组)
fig, axes = plt.subplots(2, 2, figsize=(12, 10))
# ==================== 1. 折线图(Line Plot)====================
# np.linspace(0, 10, 100):在[0, 10]区间生成100个等间距点
x = np.linspace(0, 10, 100)
# y = sin(x):计算正弦值
y = np.sin(x)
# axes[0, 0]:第一个子图(左上角)
# .plot():绘制折线图
# linewidth=2:线宽2
axes[0, 0].plot(x, y, linewidth=2)
# .set_title():设置子图标题
axes[0, 0].set_title('折线图')
# .grid():显示网格
axes[0, 0].grid(True)
# ==================== 2. 柱状图(Bar Chart)====================
# categories:类别列表
categories = ['A', 'B', 'C', 'D']
# values:对应的数值
values = [20, 35, 30, 25]
# axes[0, 1]:第二个子图(右上角)
# .bar():绘制柱状图
# color='steelblue':柱子颜色(钢蓝色)
axes[0, 1].bar(categories, values, color='steelblue')
axes[0, 1].set_title('柱状图')
# ==================== 3. 散点图(Scatter Plot)====================
# np.random.randn(100):生成100个标准正态分布随机数
x = np.random.randn(100)
y = np.random.randn(100)
# axes[1, 0]:第三个子图(左下角)
# .scatter():绘制散点图
# alpha=0.6:点的透明度60%(重叠部分会变深)
axes[1, 0].scatter(x, y, alpha=0.6)
axes[1, 0].set_title('散点图')
# .set_xlabel():设置X轴标签
axes[1, 0].set_xlabel('X')
# .set_ylabel():设置Y轴标签
axes[1, 0].set_ylabel('Y')
# ==================== 4. 饼图(Pie Chart)====================
# sizes:各部分的大小(占比)
sizes = [30, 20, 25, 25]
# labels:各部分的标签
labels = ['股票', '债券', '现金', '其他']
# axes[1, 1]:第四个子图(右下角)
# .pie():绘制饼图
# labels:各部分的标签
# autopct='%1.1f%%':自动显示百分比(保留1位小数)
axes[1, 1].pie(sizes, labels=labels, autopct='%1.1f%%')
axes[1, 1].set_title('投资组合分布')
# ==================== 调整布局并显示 ====================
# plt.tight_layout():自动调整子图间距
plt.tight_layout()
# plt.show():显示所有子图
plt.show()